package cz.zcu.fav.rat.rest.factory;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cz.zcu.fav.rat.beans.Object;
import cz.zcu.fav.rat.beans.Period;
import cz.zcu.fav.rat.beans.Reservation;
import cz.zcu.fav.rat.dataaccess.service.ObjectService;
import cz.zcu.fav.rat.rest.beans.ReservationMapping;
import cz.zcu.fav.rat.rest.errorhandling.UnknownResourceException;

@Component
public class ReservationMappingFactory
		extends
		AbstractMappingFactory<ReservationMapping, Entry<Reservation, Collection<Period>>>
{
	@Autowired
	PeriodsMappingFactory periodsMappingFactory;

	@Autowired
	ObjectService objectService;

	@Override
	public ReservationMapping getObject()
	{
		return new ReservationMapping();
	}

	@Override
	public Class<?> getObjectType()
	{
		return ReservationMapping.class;
	}

	@Override
	public ReservationMapping getMappedObject(
			Entry<Reservation, Collection<Period>> object)
	{
		ReservationMapping reservationMapping = getObject();
		Reservation reservation = object.getKey();

		reservationMapping.setId(reservation.getId());
		reservationMapping.setObjectId(reservation.getObject().getId());
		reservationMapping.setObjectName(reservation.getObject().getName());
		reservationMapping.setPeriodical(reservation.getPeriods().size() > 1);
		reservationMapping.setPeriodCount(reservation.getPeriods().size());
		reservationMapping.setUserId(reservation.getUser().getId());
		reservationMapping.setUserName(reservation.getUser().getFirstName()
				+ " " + reservation.getUser().getSurname());
		reservationMapping.setPeriods(periodsMappingFactory
				.getMappedObject(object.getValue()));

		return reservationMapping;
	}

	@Override
	public Entry<Reservation, Collection<Period>> getRemappedObject(
			ReservationMapping object , boolean ignoreId)
	{
		Map<Reservation, Collection<Period>> map = new HashMap<Reservation, Collection<Period>>();

		Reservation reservation = new Reservation();
		reservation.setId(!ignoreId ? object.getId(): null);
		Object obj = objectService.get(object.getObjectId());
		if (obj == null)
		{
			throw new UnknownResourceException("Object with id "
					+ object.getObjectId() + " was not found");
		}

		// DO NOT FILL THE USER AS IT IS ALWAYS a currently logged one
		// User user = userService.get(resMapping.getUserId());
		// if(user == null) {
		// throw new UnknownResourceException("User with id " +
		// resMapping.getObjectId() + " was not found" );
		// }
		
		reservation.setObject(obj);

		Set<Period> periods = new HashSet<Period>(
				periodsMappingFactory.getRemappedObject(object.getPeriods(), ignoreId));

		reservation.setPeriods(periods);
		for (Period period : periods)
		{
			period.setReservation(reservation);
		}
		map.put(reservation, periods);
		return map.entrySet().iterator().next();
	}

}
